package view;
import java.net.* ;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.io.* ;


/**
 * class GetRequestsFromUserSocket - answer to users for getting from them requests
 * about changes in their dropbox
 */
public class GetRequestsFromUserSocket implements Runnable{
	
	private static GetRequestsFromUserSocket getRequestsFromUserSocket = new GetRequestsFromUserSocket();
	private int maxOfExecutors; 
	private ExecutorService clientRequestPool; //thread pool for handle one user
	boolean finish=false;

	ServerSocket serverSocket=null;
	
	//private ctor
	private GetRequestsFromUserSocket() 
	{
		maxOfExecutors=10; 
		clientRequestPool= Executors.newFixedThreadPool(maxOfExecutors);
	}
	
	
	/**
	 * @return an instance of GetRequestsFromUserSocket class (singleton)
	 */
	public static GetRequestsFromUserSocket getInstance()
	{
		return getRequestsFromUserSocket;	
	}
	
	/**
	 * answer to users for getting from them requests about changes in their dropbox
	 */
	public void run () {
	    PrintWriter out = null;
	    ObjectInputStream in = null;
	    //BufferedReader stringIn = null;

	    try { 
	    	serverSocket = new ServerSocket(4444);
	    	System.out.println("Server started");
	    }
	    catch (IOException e) { 
	    	System.err.println("Cannot listen on port 4444");
	    	return;
	    	//System.exit(-1);
	    }
	    
	    Socket clientSocket=null;
	    while(!finish){
		    try { 
		    	System.out.println("accept client socket");
		    	//answer a client
		    	clientSocket=serverSocket.accept();
		    	System.out.println("accepted client socket");
		    	System.out.println("1");
		    	out=new PrintWriter(clientSocket.getOutputStream(),true);
		    	System.out.println("2");
		    	InputStream is = clientSocket.getInputStream();
		    	System.out.println("2a");
		    	in= new ObjectInputStream(is); //
		    	
		    
		    	//for free this thread to listen to another requests
		    	clientRequestPool.execute(new MyProtocolGetUserRequest(in,out,clientSocket));
		    }
		    catch (IOException e) {
		    	System.err.println("Accept failed");
		    	e.printStackTrace();
		    	
		    }
	    }	
	    
		try {
			//close the server socket
			if ((serverSocket!=null)&&(!serverSocket.isClosed()))
				serverSocket.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
  }
	
	/**
	 * stop to accept users requests
	 */
	public void stop() {
		
		this.finish = true;
		clientRequestPool.shutdown();
		
		try {
			if ((serverSocket!=null)&&(!serverSocket.isClosed()))
				serverSocket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
